import random

from django.core.cache import cache

from libs.tx_send_sms.sms import sms_msg

from user.serializers import MultiLoginNModelSerializer, SmsLoginNModelSerializer, SmsRegisterModelSerializer, \
    SmsOnClickLoginNModelSerializer, SmsUpdatePasswordModelSerializer

from utils.common_mixin import CommonListModelMixin as ListModelMixin

from rest_framework.viewsets import ViewSet, GenericViewSet
from rest_framework.decorators import action
from user import models
from utils.common_response import APIResponse
from rest_framework.exceptions import ValidationError

from threading import Thread

from utils.my_print import new_print


class CommLoginBase:
    def _comm_login_view(self, request, *args, **kwargs):
        """
        登录公用视图
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        ser = self.get_serializer(data=request.data)
        if ser.is_valid(raise_exception=True):
            username = ser.context['username']
            token = ser.context['token']
            icon = ser.context['icon']
            return APIResponse(username=username, token=token, icon=icon)
        raise ValidationError('用户不存在')

    def _comm_register(self, request, *args, **kwargs):
        """
        注册公用视图
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        ser = self.get_serializer(data=request.data)
        ser.is_valid(raise_exception=True)
        ser.save()
        # super().create(request, *args, **kwargs)  # 只要这样写，又会走序列化
        return APIResponse(msg='注册成功')


# class ClientTypeView(GenericViewSet, ListModelMixin):
#     """
#     浏览器类型
#     """
#
#     queryset = models.ClientType.objects.filter(is_delete=False, is_show=True).all()
#     serializer_class = ClientTypeSerializer
#
#     def list(self, request, *args, **kwargs):
#         response = super(ClientTypeView, self).list(request, *args, **kwargs)
#         old_data = response.data
#         # 临时构造数据
#         temp_all_data = {}
#         new_data = {
#             'code': 100,
#             'msg': '成功',
#             'name_data': [],
#             'all_data': []
#         }
#         # 获取去重的浏览器类型
#         for item in old_data['data']:
#             bw = item['bw']
#             if bw in new_data['name_data']:
#                 continue
#             new_data['name_data'].append(item['bw'])
#
#         # 构造数据
#         for temp_item in old_data['data']:
#             # temp_item==={}
#             # 没有在的
#             if temp_item['bw'] not in temp_all_data:
#                 temp_all_data[temp_item['bw']] = {
#                     'name': temp_item['bw'],
#                     'value': 0
#                 }
#             else:
#                 temp_all_data[temp_item['bw']]['value'] += 1
#         new_data['all_data'] = temp_all_data.values()
#         response.data = new_data
#         # print(old_data)
#         # # print(new_data)
#         # print(temp_all_data)
#         return response


from celery_task.sms_task import send_sms


class UserView(CommLoginBase, GenericViewSet):
    serializer_class = MultiLoginNModelSerializer

    def get_serializer_class(self):
        if self.action == 'multi_login':
            # 多方式
            return self.serializer_class
        elif self.action == 'sms_login':
            # 短信登录
            return SmsLoginNModelSerializer
        elif self.action == 'sms_one_click_login':
            """
            一件登录注册
            """
            return SmsOnClickLoginNModelSerializer
        else:
            # 短信注册
            return SmsRegisterModelSerializer

    @action(methods=['GET'], detail=False)
    def check_mobile(self, request):
        """
        手机号是否存在
        :param request:
        :return:
        """

        mobile = request.query_params.get('mobile')
        try:
            models.User.objects.get(mobile=mobile)
            return APIResponse(msg='成功')
        except Exception:
            raise ValidationError('手机号不存在')

    @action(methods=['POST'], detail=False)
    def multi_login(self, request, *args, **kwargs):
        """
        多方式登录
        :param request:
        :return:
        """
        # 前端返回的数据 {username:xxx,password:12346}
        # 校验
        # 返回token
        return self._comm_login_view(request, *args, **kwargs)

    @action(methods=['GET'], detail=False)
    def send_sms(self, request, *args, **kwargs):
        """
        验证码发送
        :param request:
        :return:
        """

        mobile = request.query_params.get('mobile')
        if not mobile or len(mobile) != 11 or not mobile.isdigit():
            raise ValidationError('手机号不合法')
        code = random.randrange(1000, 9999)
        print(code)
        cache.set('send_sms_code_%s' % mobile, code)
        # print(cache.get('send_sms_code_%s' % mobile), 'llllllllllll')
        # 异步发送短信
        t = Thread(target=sms_msg, args=(mobile, code))
        t.start()
        # res = send_sms.delay(mobile, code)
        # new_print(res)
        # 采用celery异步发送

        # ret = sms_msg(mobile, code=code)
        # if ret:
        return APIResponse(msg='发送成功')
        # raise ValidationError('发送失败')

    @action(methods=['POST'], detail=False)
    def sms_login(self, request, *args, **kwargs):
        """
        短信登录
        :param request:
        :return:
        """
        return self._comm_login_view(request, *args, **kwargs)

    @action(methods=['POST'], detail=False)
    def sms_register(self, request, *args, **kwargs):
        """
        短信登录
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        return self._comm_register(request, *args, **kwargs)

    @action(methods=['POST'], detail=False)
    def sms_one_click_login(self, request, *args, **kwargs):
        """
        发送短信，无需密码注册
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        return self._comm_register(request, *args, **kwargs)


class PasswordGenericViewSet(CommLoginBase, GenericViewSet):
    """
    修改密码
    """
    serializer_class = SmsUpdatePasswordModelSerializer

    @action(methods=['POST'], detail=False)
    def sms_update_password(self, request, *args, **kwargs):
        """
        密码修改
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        return self._comm_login_view(request, *args, **kwargs)
